#include "juego.h"
#include <iostream>
#include <time.h>
#include <vector>
#include "colision.h"
#include "logoscene.h" 
#include "gameoverscene.h"
#include "menuscene.h"
using namespace std;


Juego::Juego(int mode){

	gravedad=30;
	velocidadSalto=20;
	nivelTecho= 0.0;	
	tiempoEntreObstaculos=0.5;
	
	colision=false;
	mostrarMensaje=false;


	this->mode=mode;
}

void Juego::AparecerObstaculos(){

	//Si se dan las probabilidades y es tiempo, aparece un obstáculo
	if(rand()%1000<250 && elapsedObstaculos>=tiempoEntreObstaculos)
	{
		int obst=rand()%6;
		
		if(!obstaculos[obst]->isActivo())		
		{
			obstaculos[obst]->SetPos(centroVista.x +  vista.GetHalfSize().x);
			obstaculos[obst]->Activar();
			elapsedObstaculos=0.0;
			VariarPulsaciones(obstaculos[obst]->GetNivel());
			sndPeep.Play();	
		}

	}	


}


void Juego::Init(){

	srand(time(NULL));	

	//Ventana
	ventana= &theEngine.GetRenderWindow();
	centroVista.x=200;
	centroVista.y=300;
	vista.SetHalfSize(200,300);
	vista.SetCenter(centroVista);
	ventana->SetView(vista);


	//Línea
	posLinea=centroVista.y-10;
        imgLinea.LoadFromFile("img/linea.png");
        sprLinea.SetImage(imgLinea);
        sprLinea.SetPosition(centroVista.x - vista.GetHalfSize().x,posLinea);


	//Fondo
	imgFondo.LoadFromFile("img/fondo.png");
	sprFondo.SetImage(imgFondo);
	sprFondo.SetPosition(centroVista.x - vista.GetHalfSize().x ,0);	

	//Personaje
	personaje=new Personaje("img/personaje.png",3,2,gravedad,velocidadSalto,nivelTecho,posLinea);
	personaje->SetPos(centroVista.x-200);
	
	
	//Obstáculos
	obstaculos[0]=new Obstaculo("img/triangulo1.png",1,posLinea);
	obstaculos[1]=new Obstaculo("img/triangulo2.png",2,posLinea);
        obstaculos[2]=new Obstaculo("img/triangulo3.png",3,posLinea);
        obstaculos[3]=new Obstaculo("img/triangulo1.png",-1,posLinea);
        obstaculos[4]=new Obstaculo("img/triangulo2.png",-2,posLinea);
        obstaculos[5]=new Obstaculo("img/triangulo3.png",-3,posLinea);

	elapsedObstaculos=0.0;

	pulsaciones=75;

	velocidadEscenario=10;	

	flechaIzq=false;
	flechaDer=false;
	

	//String
	strPulsaciones.SetPosition(centroVista.x+100,centroVista.y +190);
	strPulsaciones.SetColor(sf::Color::Green);
	strPulsaciones.SetSize(100.0);
	strPulsaciones.Scale(0.5,1);

	strReloj.SetPosition(centroVista.x+100,centroVista.y-300);
	strPulsaciones.SetColor(sf::Color::Green);
        strPulsaciones.Scale(0.5,1);


	strLimiteBajo.SetPosition(strPulsaciones.GetPosition().x-30,strPulsaciones.GetPosition().y-5);
	strLimiteBajo.SetColor(sf::Color::Red);
	strLimiteBajo.Scale(0.5,1);
	//strLimiteBajo.SetSize(0.5);
	
	strLimiteBajo.SetText("60");

	strLimiteAlto.SetPosition(strPulsaciones.GetPosition().x+40,strPulsaciones.GetPosition().y-5);
        strLimiteAlto.SetColor(sf::Color::Red);
        strLimiteAlto.Scale(0.5,1);
        //strLimiteAlto.SetSize(0.5);
	
	strLimiteAlto.SetText("90");
	
	//String mensaje
	strMensaje.SetPosition(centroVista.x-150,centroVista.y+150);
	strMensaje.SetColor(sf::Color::Red);

	sprJoy.SetPosition(strMensaje.GetPosition().x+50,strMensaje.GetPosition().y+35);	
	sprJoy.SetScale(0.5,1);

	//Sound
	buffLatidos.LoadFromFile("sound/latidos.ogg");
	buffPeep.LoadFromFile("sound/peep.ogg");
	
	sndLatidos.SetBuffer(buffLatidos);
	sndLatidos.SetLoop(true);
	sndLatidos.SetVolume(100.0);
        sndLatidos.Play();

		
	sndPeep.SetBuffer(buffPeep);	
	sndPeep.SetVolume(1.0);

	buffDead.LoadFromFile("sound/muerte.ogg");
        sndDead.SetBuffer(buffDead);
	sndDead.SetVolume(50.0);





	//Vidas
	const sf::Image &vidaImage = theTextureManager.GetTexture("img/heart.png");
	
	float x=centroVista.x -200;
	float y=centroVista.y -300;

	for(int i=0;i<15;i++)
	{	
		vidas[i].SetImage(vidaImage);
		vidas[i].SetPosition(x+(i*10) ,y);
	}
	

	//Reloj
	reloj.Reset();
	tiempo=0.0;


	finJuego=false;
        tiempoFade=3.0f;
        elapsedFade=0.0f;

}

void Juego::CleanUp(){
	
}




void Juego::Render(sf::RenderWindow &w){
	w.Clear();
	
	w.Draw(sprFondo);
	
	for(int i=0;i<personaje->GetVida();i++)
	{
		w.Draw(vidas[i]);
	}

	w.Draw(strReloj);	
	w.Draw(strPulsaciones);
	w.Draw(strLimiteBajo);
	w.Draw(strLimiteAlto);
	
	w.Draw(sprLinea);
	

	//Mensaje de Advertencia!!!!!!
	if(mostrarMensaje)
	{
		w.Draw(strMensaje);
		w.Draw(sprJoy);
	}

	
	for(int i=0;i<6;i++)
	{
		if(obstaculos[i]->isActivo())
		{
			w.Draw(*obstaculos[i]);
		}
	}
	
	w.Draw(*personaje);

	if(finJuego)
	{w.Draw(sprFade);}

}



void Juego::Update(const float &dt){

	if(!finJuego)
	{

		//vista
		centroVista.x+=velocidadEscenario;
       	 	vista.SetCenter(centroVista);


		//personaje
		personaje->Actualizar(dt);
		

		if(mode==0)	
			personaje->SetPos(centroVista.x-200);
		else
			personaje->SetPosB(centroVista.x-200);


		AparecerObstaculos();

		//Controla que los obstáculos sigan en pantalla
		for(int i=0;i<6;i++)
		{
			if(obstaculos[i]->isActivo())
			{
				if(obstaculos[i]->GetPosition().x +obstaculos[i]->GetW()  <  (centroVista.x - vista.GetHalfSize().x  ) )
					obstaculos[i]->Desactivar();
			}	
		}


		ControlarLimites();
	
		//tiempo de aparición de obstáculos
		elapsedObstaculos+=dt;


		//Línea
		sprLinea.SetPosition(centroVista.x - vista.GetHalfSize().x,centroVista.y+1);
	
		//Fondo
		sprFondo.SetPosition(centroVista.x - vista.GetHalfSize().x ,0);

	
		DetectarColisiones();
		colision=false;


		//velocidad pulsaciones
		CalcularVelocidadEscenario();

		//Reloj
		tiempo=reloj.GetElapsedTime();

		sprintf(aux,"%3.3f",tiempo);
		strReloj.SetText(aux);
		strReloj.SetPosition(centroVista.x+100,centroVista.y-300);


		//String pulsaciones
		sprintf(aux,"%i",pulsaciones);
		strPulsaciones.SetText(aux);
		strPulsaciones.SetPosition(centroVista.x+100,centroVista.y + 190);
	
		strLimiteBajo.SetPosition(strPulsaciones.GetPosition().x-30,strPulsaciones.GetPosition().y-5);
		strLimiteAlto.SetPosition(strPulsaciones.GetPosition().x+40,strPulsaciones.GetPosition().y-5);
		
		if(mostrarMensaje)
		{
			strMensaje.SetPosition(centroVista.x-150,centroVista.y+150);
			sprJoy.SetPosition(strMensaje.GetPosition().x+50,strMensaje.GetPosition().y+35);  
		}	


		//Vidas
		float x=centroVista.x -200;
       		float y=centroVista.y-300;

        	for(int i=0;i<15;i++)
        	{
			vidas[i].SetPosition(x+(i*10) ,y);
        	}



		if(flechaIzq)
		{
			flechaIzq=false;
		
			if(pulsaciones>90)
				VariarPulsaciones(-1);		
		}
		
		if(flechaDer)
		{
			flechaDer=false;
		
			if(pulsaciones<60)
				VariarPulsaciones(1);
		}


		
		if(CheckFinJuego())
		{
			finJuego=true;
			imgFade.LoadFromFile("img/fade.png");
			sprFade.SetImage(imgFade);
        		sprFade.SetPosition(centroVista.x- vista.GetHalfSize().x ,0);
			
			sndLatidos.Stop();
			sndDead.Play();


		}
	
	}
	else
	{	
		if(elapsedFade>=tiempoFade)
		{		
			ventana->SetView(ventana->GetDefaultView());
			theEngine.AppendScene(new GameOverScene(tiempo));
			theEngine.AppendScene(new MenuScene());
			EndScene();
		}
		else
		{	
			float alpha;
			elapsedFade+=dt;
			sprFade.SetColor(sf::Color(255,255,255, elapsedFade*255));
		
		}
	
	}
}


void Juego::ProcessEvent(const sf::Event &e){
		
	if(e.Type==sf::Event::KeyPressed)
	{

		if(mode==0)
		{	
			if(e.Key.Code==sf::Key::Space)
			{
				personaje->Saltar();
			}
		}
		else
		{	
			if(e.Key.Code==sf::Key::Up)
			{	
				personaje->FlipY(false);
				personaje->vuelta=true;
			}

			if(e.Key.Code==sf::Key::Down)
                        {
                                personaje->FlipY(true);
                                personaje->vuelta=false;
                                
                        }
			
	
		}
	
		if(e.Key.Code==sf::Key::Left && flechaIzqHabilitada)
		{	
			flechaIzq=true;
			flechaIzqHabilitada=false;
		}
		if(e.Key.Code==sf::Key::Right && flechaDerHabilitada)
                { 
			flechaDer=true;
			flechaDerHabilitada=false;
		}
		
	}

	if(e.Type==sf::Event::KeyReleased)
	{
		if(e.Key.Code==sf::Key::Left)
		{
                	flechaIzq=false;
			flechaIzqHabilitada=true;
		}
                if(e.Key.Code==sf::Key::Right)
                {        
			flechaDer=false;
			flechaDerHabilitada=true;
		}
	}

	//Joystick!!!!!

	if(e.Type==sf::Event::JoyButtonPressed)
	{	
		if(e.JoyButton.Button==0)
			personaje->Saltar();			
	}

	if(e.Type==sf::Event::JoyMoved)
	{	
		if(e.JoyMove.Position>0)
		{
			flechaDer=false;
                        flechaDerHabilitada=true;
		}	

		if(e.JoyMove.Position<0)
		{
			flechaIzq=false;
                        flechaIzqHabilitada=true;
		}

	}

}

void Juego::DetectarColisiones(){
	
	for(int i=0;i<6;i++)
	{
		if(!colision)
		{	
			if(obstaculos[i]->isActivo())
			{
				if(Collision::PixelPerfectTest(*personaje,*obstaculos[i]))
				{
					colision=true;
					VariarPulsaciones(obstaculos[i]->GetNivel()*2);
					obstaculos[i]->Desactivar();
					personaje->RestarVida();
				}
			}
		}
	}

}

void Juego::VariarPulsaciones(int p){

	pulsaciones+=p;

}

void Juego::CalcularVelocidadEscenario(){

	if(pulsaciones < 70)
	{
		velocidadEscenario=8;
		sndLatidos.SetPitch(0.5);
	}
	else if(pulsaciones>70 && pulsaciones <90)
	{	
		velocidadEscenario=10;
		sndLatidos.SetPitch(1.0);

	}	
	else if(pulsaciones>90 && pulsaciones <110)
	{	
		velocidadEscenario=15;
		sndLatidos.SetPitch(1.5);

	}
	else if (pulsaciones> 125)
	{
		velocidadEscenario=18;
                sndLatidos.SetPitch(1.8);
	}
	else
	{
		velocidadEscenario=20;
                sndLatidos.SetPitch(2.0);
	}
}

bool Juego::CheckFinJuego(){

	if(pulsaciones<30 || pulsaciones>140)
	{	return true;}
	

	if(personaje->GetVida()<=0)
		return true;

	return false;	
}

void Juego::ControlarLimites(){
	
	if(pulsaciones<60)
	{
		const sf::Image &img = theTextureManager.GetTexture("img/gamepad_der.png");	
		sprJoy.SetImage(img);
		strMensaje.SetText("Low Pulse!");
		mostrarMensaje=true;
	}
	else if(pulsaciones>90)
	{	
		const sf::Image &img = theTextureManager.GetTexture("img/gamepad_izq.png");      
                sprJoy.SetImage(img);
		strMensaje.SetText("Elevate Pulse!");
                mostrarMensaje=true;
	}
	else
		mostrarMensaje=false;

}
